<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>原型链</title>
</head>
<body>
    <p>
				创建对象有几种方法
				原型、构造函数、实例、原型链
				instanceof的原理
				new 运算符
		</p>
		<script>
			// 字面量方式
			let o1  = { name: 'o1 '}

			let o11 = new Object({ name: 'o11'})
			// 3.构造函数的方式
			let M = function (name) { this.name = name }
			let o2 = new M('o2')

			// 将对象转为新对象的__proto__
			let p = {name: 'o3'}
			let o3 = Object.create(p)
		</script>
		<h1 style="color: red">原型、构造函数、实例、原型链的关系</h1>
		<p>
			只有（构造）函数才有prototype，只有实例对象才有__proto__<br>
			只有构造函数对象的实例对象，他们之间的prototype和__proto__是相同的指向的<br>
			构造函数的prototype的constructor指向构造函数本身<br>
			实例对象没有的属性会去__proto__对象去查找，如果__proto__没有则去原型对象的__proto__上查找，<br>
			函数既是Function构造函数的实例对象也是函数，所以函数既有__proto__对象也有prototype<br>
		</p>

		<h1 style="color: red">关于instanceof</h1>
		<p>
			用 实例对象instanceof构造函数来判断一个对象是不是一个构造函数的实例<br>
			但是只要是在对象和构造函数一条原型链上的构造函数，用instanceof都为true，比如instanceof构造函数，也instanceof Object<br>
			所以用instanceof不能准确判断一个对象是不是一个构造函数的实例<br>
			而是应该用obj.__proto__.constructor === 构造函数 来判断是不是构造函数的实例<br>
		</p>

		<h1 style="color: red">实现new 运算符</h1>
		<script>
			let new2 = function(func) {
			 let o = Object.create(func.prototype)
			 let k = func.call(o)
			 if (typeof k === 'object') {
				 return k
			 }
			 return o
			}
			let M2 = function(){
				this.name = 'name'
			}
			let o = new2(M2)
			console.log(o)
		</script>
</body>
</html>